package viper.ji;

import java.awt.*;
import java.io.IOException;
import java.util.Vector;
import java.util.Enumeration;
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
import javax.media.datasink.*;
import javax.media.control.MonitorControl;
import java.io.*;
import java.net.*;

public class Extractor implements BufferTransferHandler {

	DataSource ds;
	PushBufferStream streams[];
	Buffer buff;
	LiveStream ls;
	Buffer boofer;
	DatagramSocket sock;
	InetAddress destIP;
	int destPort;

	public Extractor(DataSource src, InetAddress ip, int port){
		//DataSource containing the digitized audio stream is a push-type stream
		streams = ((PushBufferDataSource)src).getStreams();

		// There's only a single audio stream in the DataSource
		streams[0].setTransferHandler(this);

		ds = src;
		buff = new Buffer();
		boofer = new Buffer();
		
		ls = new LiveStream();
		
		try{
		sock = new DatagramSocket();
		}catch(SocketException se){
			System.err.println("Failed to open socket.");
		}
		
		destIP = ip;
		destPort = port;
		
		System.out.println("-> Destination Host identified as: " + destIP + "/" + port);
	}
	
	public LiveStream getLiveStream(){
		return ls;
	}
	
	public PushBufferStream getStream(){
		return streams[0];
	}

	public void start() {
		try {
			ds.start();
		} catch (IOException e) {
			System.err.println(e);
		}
	}

	public void stop() {
		try {
			ds.stop();
		} catch (IOException e) {
			System.err.println(e);
		}
	}

	/** This will get called when there's data pushed from the PushBufferDataSource. */
	public void transferData(PushBufferStream stream) {
		try {
			stream.read(buff);
		} catch (IOException e) {
			System.err.println(e);
			return;
		}
		printDataInfo(buff);
	}

	void printDataInfo(Buffer buffer) {
		/** Extracted byte[] debug messages **/
		/*
		System.out.println("Read audio data:");
		System.out.println("  Time stamp: " + buffer.getTimeStamp());
		System.out.println("  Sequence #: " + buffer.getSequenceNumber());
		System.out.println("  Data length: " + buffer.getLength());
		System.out.println("  Data Format: " + buffer.getFormat());
		System.out.println("  Header: " + buffer.getHeader()); //32864
		System.out.println("  Flags: " + buffer.getFlags());
		
		System.out.println(((byte[])buffer.getData()).length);
		System.out.println("  Data: ");
		byte[] temp = (byte[])buffer.getData();
		for(int i=0;i<temp.length;i++){
			System.out.print(temp[i]+" ");
		}System.out.println("");
		*/
		
		byte[] toSend = (byte[])buffer.getData();
		try{
			sock.send(new DatagramPacket(toSend,0,toSend.length,destIP,destPort));
		}catch(Exception e){
			System.err.println("Failed to send packet, SeqNo: "+buffer.getSequenceNumber());
		}
		
		/** Testing locally, build stream from "received" packets. **/
		//ls.update((byte[])buffer.getData());
		
		/** Testing locally, received stream debug messages. **/
		/*
		try{
			ls.read(boofer);
		}catch(IOException e){
			System.err.println(e);
		}
		System.out.println("DEBUG:::::::::::");
		System.out.println(boofer.getTimeStamp());
		System.out.println(boofer.getSequenceNumber());
		System.out.println(boofer.getLength());
		System.out.println(boofer.getFormat());
		System.out.println((byte[])boofer.getData());
		byte[] tempp = (byte[])boofer.getData();
		for(int i=0;i<tempp.length;i++){
			System.out.print(tempp[i]+" ");
		}System.out.println("");
		System.out.println("::::::::::::::::");
		
		for(int i=0;i<temp.length;i++){
			if(temp[i]!=tempp[i])
				System.out.println("NOT EQUAL@@@@@@@@@@@@@@@@@@@");
		}
		*/
		
		/*
		Object data = buffer.getData();
		if (data instanceof byte[]) {
			System.out.println("write byte array data");
			try {
				dout.write((byte[]) data);
				dout.flush();
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (buffer.isEOM())
			System.err.println("  Got EOM!");
		 */
	}

}

